using Microsoft.Extensions.DependencyInjection;
using admin.application.Services;
using Microsoft.Extensions.Configuration;
using admin.application.contracts.Services;
using admin.application.contracts.Configurations;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using admin.core.Services;
using admin.core.Repositories;
using admin.infrastructure.Repositories;
using MediatR;
using admin.core.Entities.App;
using admin.application.Notifications;
using System.Data;

namespace admin.application;

public static class ServicesCollectionExtension
{
    public static IServiceCollection AddApplication(this IServiceCollection service)
    {
        service.AddScoped(typeof(AppAuthService)); 
        service.AddScoped<IAppUserService, AppUserService>();
        service.AddScoped<IAppRoleServices, AppRoleServices>();
        service.AddScoped<IAppPermissionService, AppPermissionService>();
        service.AddScoped<ImageAppService>();
        service.AddScoped<IAppImageService, AppImageService>();
        service.AddScoped(typeof(IRepository<>), typeof(DapperRepository<>));
        service.AddScoped<IAppImageRepository, AppImageRepository>();
        service.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<RoleCreatedEventHandler>());
        service.AddScoped<IAppRoleServices, AppRoleServices>(provider =>
            new AppRoleServices(
                provider.GetRequiredService<IRepository<AppRole>>(),
                provider.GetRequiredService<IRepository<AppPermission>>(),
                provider.GetRequiredService<IMediator>(),
                provider.GetRequiredService<IDbConnection>()
            )
        );
        service.AddScoped<AppAuthService>(provider =>
            new AppAuthService(
                provider.GetRequiredService<IRepository<AppUser>>(),
                provider.GetRequiredService<IRepository<AppRole>>(),
                provider.GetRequiredService<IAppUserService>(),
                provider.GetRequiredService<IDbConnection>(),
                provider.GetRequiredService<IMediator>()
            )
        );
        return service;
    }

    public static IServiceCollection AddJwtTokenService(this IServiceCollection services, IConfiguration configuration)
    {
        services.Configure<JwtSettings>(configuration.GetSection("Jwt"));
        services.AddScoped<IJwtTokenService, JwtTokenService>();
        
        return services;
    }

    public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, IConfiguration configuration)
    {
        var jwtSection = configuration.GetSection("Jwt");
        services.Configure<JwtSettings>(jwtSection);
        var jwtSettings = jwtSection.Get<JwtSettings>();
        
        // 如果配置为空，使用默认值
        if (jwtSettings == null)
        {
            jwtSettings = new JwtSettings
            {
                Issuer = "DefaultIssuer",
                Audience = "DefaultAudience",
                SecretKey = "YourSecretKeyHere123456789012345678901234567890",
                ExpireMinutes = 120,
                ClockSkewSeconds = 60,
                RefreshTokenExpireMinutes = 1440
            };
        }
        
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = "JwtBearer";
            options.DefaultChallengeScheme = "JwtBearer";
        })
        .AddJwtBearer("JwtBearer", options =>
        {
            options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = jwtSettings.Issuer,
                ValidAudience = jwtSettings.Audience,
                IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(jwtSettings.SecretKey)),
                ClockSkew = System.TimeSpan.FromSeconds(jwtSettings.ClockSkewSeconds)
            };
        });
        return services;
    }
}